﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.Serialization;

namespace Common
{
    /// <summary>
    /// 异常基类。
    /// 错误代码 Code 可以按照现有的功能编号进行改造。
    /// </summary>
    [Serializable]
    public class BaseException : ApplicationException
    {
        private string _code = string.Empty;
        private string _message = string.Empty;
        private string _innerMessage = string.Empty;
        private string _innerStack = string.Empty;

        /// <summary>
        /// 异常代码
        /// </summary>
        public string Code
        {
            get { return _code; }
        }

        /// <summary>
        /// 异常信息
        /// </summary>
        public override string Message
        {
            get { return _message; }
        }

        /// <summary>
        /// 内部异常信息
        /// </summary>
        public string InnerMessage
        {
            get { return _innerMessage; }
        }

        /// <summary>
        /// 内部异常堆栈信息
        /// </summary>
        public string InnerStack
        {
            get { return _innerStack; }
        }

        /// <summary>
        /// 构造方法
        /// </summary>
        /// <param name="message">异常消息</param>
        public BaseException(string message)
            : base(message)
        {
        }

        /// <summary>
        /// 构造函数，二进制反序列化时使用
        /// </summary>
        /// <param name="info">序列化对象数据</param>
        /// <param name="context">上下文信息</param>
        protected BaseException(SerializationInfo info, StreamingContext context)
            : base(info, context)
        {
            _code = info.GetString("ErrorCode");
            _message = info.GetString("ErrorMessage");
        }


        /// <summary>
        /// 构造方法
        /// </summary>
        /// <param name="code">异常编码</param>
        /// <param name="message">异常消息</param>
        public BaseException(string code, string message)
            : base(FormatMessage(code, message))
        {
            _code = code;
            _message = message;
        }

        /// <summary>
        /// 构造方法
        /// </summary>
        /// <param name="message">异常消息</param>
        /// <param name="innerException">嵌套异常</param>
        public BaseException(string message, System.Exception innerException)
            : base(message, innerException)
        {
            _message = message;
            _innerStack = innerException == null ? null : innerException.StackTrace;
            _innerMessage = innerException == null ? null : innerException.Message;
        }

        /// <summary>
        /// 构造方法
        /// </summary>
        /// <param name="code">异常编码</param>
        /// <param name="message">异常消息</param>
        /// <param name="innerException">嵌套异常类</param>
        public BaseException(string code, string message, System.Exception innerException)
            : base(FormatMessage(code, message), innerException)
        {
            _code = code;
            _message = message;
            _innerStack = innerException == null ? null : innerException.StackTrace;
            _innerMessage = innerException == null ? null : innerException.Message;
        }

        /// <summary>
        /// 构造方法
        /// </summary>
        /// <param name="code">异常编码</param>
        /// <param name="innerException">嵌套异常类</param>
        /// <param name="messageFormat">异常消息格式化串</param>
        /// <param name="messageParams">异常消息参数值</param>
        public BaseException(string code, System.Exception innerException, string messageFormat, params string[] messageParams)
            : base(FormatMessage(code, string.Format(messageFormat, messageParams)), innerException)
        {
            _code = code;
            _message = string.Format(messageFormat, messageParams);
            _innerStack = innerException == null ? null : innerException.StackTrace;
            _innerMessage = innerException == null ? null : innerException.Message;
        }

        private static string FormatMessage(string code, string message)
        {
            return string.Format("[ErrorCode: {0}]{1}", code, message);
        }

        /// <summary>
        /// 设置序列化信息
        /// </summary>
        /// <param name="info">序列化对象</param>
        /// <param name="context">上下文</param>
        public override void GetObjectData(SerializationInfo info, StreamingContext context)
        {
            info.AddValue("ErrorCode", _code);
            info.AddValue("ErrorMessage", _message);
            base.GetObjectData(info, context);
        }

        /// <summary>
        /// 格式化异常信息内容输出
        /// </summary>
        /// <returns>格式化异常信息内容</returns>
        public override string ToString()
        {
            return "BaseException: " + Message + " Wrapped exception: " + base.ToString();
        }
    }
}

